package com.sea.base.utils

import android.app.Activity
import android.graphics.Rect
import android.view.View
import android.view.ViewTreeObserver
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import com.sea.base.R
import com.sea.base.ext.global.SCREEN_HEIGHT
import com.sea.base.ext.view.getTypeTag

object KeyboardUtils {
    /**
     * @param view 任意view
     */
    @JvmStatic
    @Suppress("NOTHING_TO_INLINE")
    inline fun hideKeyboard(view: View) {
        view.clearFocus()
        val imm = view.context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.hideSoftInputFromWindow(view.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
    }

    /**
     * @param view 任意view
     */
    @Suppress("NOTHING_TO_INLINE")
    inline fun showKeyboard(view: EditText) {
        view.isFocusable = true
        view.isFocusableInTouchMode = true
        view.requestFocus()
        val imm = view.context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT)
    }

    /**
     * @param view 任意view，每个view可添加一个监听
     * @param onChangedListener true：键盘弹起
     */
    fun setOnKeyboardChangedListener(view: View, onChangedListener: (isShowing: Boolean) -> Unit) {
        val cacheData = object {
            var mShowInput: Boolean? = null
            var mRect = Rect()
        }

        removeOnKeyboardChangedListener(view)

        //新创建一个
        val listener = ViewTreeObserver.OnGlobalLayoutListener {
            view.post {
                val showInput = isKeyboardShowing(view, cacheData.mRect)
                if (cacheData.mShowInput == null || cacheData.mShowInput != showInput) { //键盘状态变化
                    cacheData.mShowInput = showInput
                    onChangedListener(showInput)
                }
            }
        }
        view.setTag(R.id.tag_keyboard_tree_listener, listener)
        view.viewTreeObserver.addOnGlobalLayoutListener(listener)
        //view被删除后应取消相关监听，但是单纯的remove反而会引起更多问题，鉴于场景几乎没有，暂时忽略
//        view.doOnDetach { view.viewTreeObserver.removeOnGlobalLayoutListener(listener) }
    }

    fun removeOnKeyboardChangedListener(view: View) {
        view.getTypeTag<ViewTreeObserver.OnGlobalLayoutListener>(R.id.tag_keyboard_tree_listener)?.let {
            view.viewTreeObserver.removeOnGlobalLayoutListener(it)
        }
    }

    private fun isKeyboardShowing(view: View, rect: Rect): Boolean {
        val screenHeight = SCREEN_HEIGHT
        //获取屏幕底部坐标
        view.rootView.getWindowVisibleDisplayFrame(rect)
        //获取键盘的高度
        val heightDifference = screenHeight - rect.bottom
        return heightDifference > screenHeight / 5
    }

    fun isKeyboardShowing(view: View) = isKeyboardShowing(view, Rect())
}